package com.commerce.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.commerce.common.entity.FlashSaleProduct;
import com.commerce.common.message.FlashSaleMessage;
import com.commerce.product.mapper.FlashSaleProductMapper;
import com.commerce.product.service.FlashSaleOrderService;
import com.commerce.product.service.FlashSaleStockService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;

/**
 * 秒杀订单处理服务实现
 */
@Slf4j
@Service
public class FlashSaleOrderServiceImpl implements FlashSaleOrderService {

    @Autowired
    private FlashSaleProductMapper flashSaleProductMapper;

    @Autowired
    private FlashSaleStockService flashSaleStockService;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    @Transactional
    public boolean processFlashSaleOrder(FlashSaleMessage message) {
        try {
            log.info("开始处理秒杀订单: messageId={}, userId={}, productId={}", 
                    message.getMessageId(), message.getUserId(), message.getProductId());

            // 1. 创建订单
            String orderNo = createFlashSaleOrder(message);
            if (orderNo == null) {
                log.error("创建秒杀订单失败: messageId={}", message.getMessageId());
                return false;
            }

            // 2. 扣减数据库库存
            boolean stockDeducted = deductDatabaseStock(
                message.getFlashSaleId(), 
                message.getProductId(), 
                message.getQuantity()
            );

            if (!stockDeducted) {
                log.error("扣减数据库库存失败: messageId={}, orderNo={}", 
                         message.getMessageId(), orderNo);
                
                // 库存扣减失败，需要取消订单
                cancelOrder(orderNo);
                return false;
            }

            // 3. 更新消息状态
            message.setSuccess(orderNo);
            
            log.info("秒杀订单处理成功: messageId={}, orderNo={}, userId={}", 
                    message.getMessageId(), orderNo, message.getUserId());
            
            return true;

        } catch (Exception e) {
            log.error("处理秒杀订单异常: messageId={}, error={}", 
                     message.getMessageId(), e.getMessage(), e);
            
            message.setFailed("订单处理异常: " + e.getMessage());
            return false;
        }
    }

    @Override
    public boolean rollbackStock(FlashSaleMessage message) {
        try {
            log.info("开始回滚库存: messageId={}, flashSaleId={}, productId={}, quantity={}", 
                    message.getMessageId(), message.getFlashSaleId(), 
                    message.getProductId(), message.getQuantity());

            // 回滚Redis库存
            flashSaleStockService.rollbackStock(
                message.getFlashSaleId(), 
                message.getProductId(), 
                message.getQuantity()
            );

            // 回滚数据库库存
            restoreDatabaseStock(
                message.getFlashSaleId(), 
                message.getProductId(), 
                message.getQuantity()
            );

            log.info("库存回滚成功: messageId={}", message.getMessageId());
            return true;

        } catch (Exception e) {
            log.error("库存回滚异常: messageId={}, error={}", 
                     message.getMessageId(), e.getMessage(), e);
            return false;
        }
    }

    @Override
    public boolean handleOrderTimeout(FlashSaleMessage message) {
        try {
            log.info("处理订单超时: messageId={}, orderNo={}", 
                    message.getMessageId(), message.getOrderNo());

            // 如果订单已创建但未支付，取消订单并回滚库存
            if (message.getOrderNo() != null) {
                // 取消订单
                boolean cancelled = cancelOrder(message.getOrderNo());
                if (cancelled) {
                    // 回滚库存
                    return rollbackStock(message);
                }
            } else {
                // 订单未创建，只需回滚库存
                return rollbackStock(message);
            }

            return false;

        } catch (Exception e) {
            log.error("处理订单超时异常: messageId={}, error={}", 
                     message.getMessageId(), e.getMessage(), e);
            return false;
        }
    }

    @Override
    public void handleFailedOrder(FlashSaleMessage message) {
        try {
            log.error("处理失败订单: messageId={}, userId={}, productId={}, reason={}", 
                     message.getMessageId(), message.getUserId(), 
                     message.getProductId(), message.getErrorMessage());

            // 回滚库存
            rollbackStock(message);

            // 这里可以添加失败订单的记录逻辑
            // 例如：记录到失败订单表、发送通知等

        } catch (Exception e) {
            log.error("处理失败订单异常: messageId={}, error={}", 
                     message.getMessageId(), e.getMessage(), e);
        }
    }

    @Override
    public String createFlashSaleOrder(FlashSaleMessage message) {
        try {
            // 构建订单数据
            Map<String, Object> orderData = new HashMap<>();
            orderData.put("userId", message.getUserId());
            orderData.put("totalAmount", message.getFlashPrice().multiply(
                java.math.BigDecimal.valueOf(message.getQuantity())));
            orderData.put("remark", "秒杀订单");
            
            // 构建订单项
            Map<String, Object> orderItem = new HashMap<>();
            orderItem.put("productId", message.getProductId());
            orderItem.put("productName", message.getProductName());
            orderItem.put("price", message.getFlashPrice());
            orderItem.put("quantity", message.getQuantity());
            
            orderData.put("items", java.util.Arrays.asList(orderItem));

            // 调用订单服务创建订单
            HttpHeaders headers = new HttpHeaders();
            headers.set("Content-Type", "application/json");
            headers.set("X-User-Id", message.getUserId().toString());
            
            HttpEntity<Map<String, Object>> request = new HttpEntity<>(orderData, headers);
            
            ResponseEntity<Map> response = restTemplate.exchange(
                "http://commerce-order-service/api/orders",
                HttpMethod.POST,
                request,
                Map.class
            );

            if (response.getStatusCode().is2xxSuccessful() && response.getBody() != null) {
                Map<String, Object> responseBody = response.getBody();
                if ("200".equals(responseBody.get("code").toString())) {
                    Map<String, Object> orderInfo = (Map<String, Object>) responseBody.get("data");
                    return orderInfo.get("orderNo").toString();
                }
            }

            log.error("调用订单服务失败: response={}", response.getBody());
            return null;

        } catch (Exception e) {
            log.error("创建秒杀订单异常: messageId={}, error={}", 
                     message.getMessageId(), e.getMessage(), e);
            return null;
        }
    }

    @Override
    @Transactional
    public boolean deductDatabaseStock(Long flashSaleId, Long productId, Integer quantity) {
        try {
            LambdaUpdateWrapper<FlashSaleProduct> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(FlashSaleProduct::getFlashSaleId, flashSaleId)
                        .eq(FlashSaleProduct::getProductId, productId)
                        .ge(FlashSaleProduct::getStock, quantity) // 确保库存充足
                        .setSql("stock = stock - " + quantity)
                        .setSql("sold_count = sold_count + " + quantity)
                        .set(FlashSaleProduct::getUpdateTime, LocalDateTime.now());

            int updated = flashSaleProductMapper.update(null, updateWrapper);
            
            if (updated > 0) {
                log.info("数据库库存扣减成功: flashSaleId={}, productId={}, quantity={}", 
                        flashSaleId, productId, quantity);
                return true;
            } else {
                log.warn("数据库库存扣减失败，可能库存不足: flashSaleId={}, productId={}, quantity={}", 
                        flashSaleId, productId, quantity);
                return false;
            }

        } catch (Exception e) {
            log.error("扣减数据库库存异常: flashSaleId={}, productId={}, quantity={}, error={}", 
                     flashSaleId, productId, quantity, e.getMessage(), e);
            return false;
        }
    }

    @Override
    @Transactional
    public boolean restoreDatabaseStock(Long flashSaleId, Long productId, Integer quantity) {
        try {
            LambdaUpdateWrapper<FlashSaleProduct> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(FlashSaleProduct::getFlashSaleId, flashSaleId)
                        .eq(FlashSaleProduct::getProductId, productId)
                        .setSql("stock = stock + " + quantity)
                        .setSql("sold_count = sold_count - " + quantity)
                        .set(FlashSaleProduct::getUpdateTime, LocalDateTime.now());

            int updated = flashSaleProductMapper.update(null, updateWrapper);
            
            log.info("数据库库存恢复: flashSaleId={}, productId={}, quantity={}, updated={}", 
                    flashSaleId, productId, quantity, updated);
            
            return updated > 0;

        } catch (Exception e) {
            log.error("恢复数据库库存异常: flashSaleId={}, productId={}, quantity={}, error={}", 
                     flashSaleId, productId, quantity, e.getMessage(), e);
            return false;
        }
    }

    /**
     * 取消订单
     */
    private boolean cancelOrder(String orderNo) {
        try {
            // 调用订单服务取消订单
            ResponseEntity<Map> response = restTemplate.exchange(
                "http://commerce-order-service/api/orders/" + orderNo + "/cancel",
                HttpMethod.PUT,
                null,
                Map.class
            );

            return response.getStatusCode().is2xxSuccessful();

        } catch (Exception e) {
            log.error("取消订单异常: orderNo={}, error={}", orderNo, e.getMessage(), e);
            return false;
        }
    }
}
